﻿namespace NMortgage.UI.Tests.ViewModels
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;

    using Microsoft.VisualStudio.TestTools.UnitTesting;

    using NMortgage.UI.Events;
    using NMortgage.UI.Model;
    using NMortgage.UI.Properties;
    using NMortgage.UI.ViewModels;

    [TestClass]
    public class SimulationViewModelTest : TestBase<SimulationViewModel>
    {
        #region Methods

        [TestMethod]
        public void ShowAmortization_Calculates_Biweekly_Dates_Correctly()
        {
            // Arrange
            SetupForShowAmortization();
            Subject.LoanProfileViewModel.SelectedPaymentFrequency = PaymentFrequency.Biweekly;
            var expected = new[]
                               {
                                   new DateTime(2012,4,30),
                                   new DateTime(2012,5,14),
                                   new DateTime(2012,5,28),
                                   new DateTime(2012,6,11),
                                   new DateTime(2012,6,25),
                                   new DateTime(2012,7,9),
                                   new DateTime(2012,7,23),
                                   new DateTime(2012,8,6),
                                   new DateTime(2012,8,20),
                                   new DateTime(2012,9,3),
                                   new DateTime(2012,9,17),
                                   new DateTime(2012,10,1),
                                   new DateTime(2012,10,15),
                                   new DateTime(2012,10,29),
                                   new DateTime(2012,11,12),
                                   new DateTime(2012,11,26),
                                   new DateTime(2012,12,10),
                                   new DateTime(2012,12,24),
                                   new DateTime(2013,1,7),
                                   new DateTime(2013,1,21),
                                   new DateTime(2013,2,4),
                                   new DateTime(2013,2,18),
                                   new DateTime(2013,3,4),
                                   new DateTime(2013,3,18),
                               };
            // Act
            Subject.ShowAmortization();
            // Assert
            var actual = Subject.Payments.Select(x => x.PaymentDate).ToList();
            CollectionAssert.AreEqual(expected, actual);
        }

        [TestMethod]
        public void ShowAmortization_Calculates_Monthly_Dates_Correctly()
        {
            // Arrange
            SetupForShowAmortization();
            Subject.LoanProfileViewModel.SelectedPaymentFrequency = PaymentFrequency.Monthly;
            var expected = new[]
                               {
                                   new DateTime(2012,5,16),
                                   new DateTime(2012,6,16),
                                   new DateTime(2012,7,16),
                                   new DateTime(2012,8,16),
                                   new DateTime(2012,9,16),
                                   new DateTime(2012,10,16),
                                   new DateTime(2012,11,16),
                                   new DateTime(2012,12,16),
                                   new DateTime(2013,1,16),
                                   new DateTime(2013,2,16),
                                   new DateTime(2013,3,16),
                                   new DateTime(2013,4,16),
                               };
            // Act
            Subject.ShowAmortization();
            // Assert
            var actual = Subject.Payments.Select(x => x.PaymentDate).ToList();
            CollectionAssert.AreEqual(expected, actual);
        }

        [TestMethod]
        public void ShowAmortization_Calculates_Monthly_Dates_Correctly_When_At_End_Of_Month()
        {
            // Arrange
            SetupForShowAmortization();
            Subject.LoanProfileViewModel.SelectedPaymentFrequency = PaymentFrequency.Monthly;
            Subject.LoanProfileViewModel.StartDate = new DateTime(2012, 3, 31);
            var expected = new[]
                               {
                                   new DateTime(2012,4,30),
                                   new DateTime(2012,5,31),
                                   new DateTime(2012,6,30),
                                   new DateTime(2012,7,31),
                                   new DateTime(2012,8,31),
                                   new DateTime(2012,9,30),
                                   new DateTime(2012,10,31),
                                   new DateTime(2012,11,30),
                                   new DateTime(2012,12,31),
                                   new DateTime(2013,1,31),
                                   new DateTime(2013,2,28),
                                   new DateTime(2013,3,31),
                               };
            // Act
            Subject.ShowAmortization();
            // Assert
            var actual = Subject.Payments.Select(x => x.PaymentDate).ToList();
            CollectionAssert.AreEqual(expected, actual);
        }

        [TestMethod]
        public void Title_Should_Be_From_Resources()
        {
            var expected = Resources.SimulationTitle;
            var actual = Subject.Title;
            Assert.AreEqual(expected, actual);
        }

        private void SetupForShowAmortization()
        {
            var loanProfile = Subject.LoanProfileViewModel;
            var parameter = new InterestParameter(DistributionType.FixedRate);
            parameter.Years = 1;
            parameter.Months = 0;
            var rate = parameter.Distribution as FixedRate;
            rate.Rate = 5;
            loanProfile.InterestRates.Handle(new ProfileItemAdded(parameter));
            loanProfile.LoanAmount = 50000;
            loanProfile.TermLength = 1;
            loanProfile.StartDate = new DateTime(2012, 4, 16);
        }

        #endregion Methods
    }
}